package com.example.common;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.CellStyle;

import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;


public class ExcelUtil {

    /**
     * Excel表格导出模板类
     * @param response response对象，返回的是流数据
     * @param list 数据源对象，这里就是最后的列表
     * @param filename 自己定义的文件名。（前后端分离时，无法返回正确的文件名，这里的文件名一般是前端写好传递过来的）
     * @throws IOException
     */
    public static void exportExcelUtil(HttpServletResponse response, List<LinkedHashMap<String,Object>> list, String filename) throws IOException {
        /**创建Excel文件*/
        HSSFWorkbook  sxssfWorkbook = new HSSFWorkbook ();

        /**创建sheet页*/
        HSSFSheet sheet = sxssfWorkbook.createSheet(filename);
        /**设置每一列单元格的宽度，因为一个单元格宽度定了，那么下面多有的单元格高度都确定了，所以这个方法是sheet的*/
        int z=0;
        sheet.setColumnWidth((short)z++, 10*256);//第一列
        sheet.setColumnWidth((short)z++, 12*256);//第二列
        sheet.setColumnWidth((short)z++, 10*256);//第三列
        sheet.setColumnWidth((short)z++, 13*256);//第四列


        /**有得时候你想设置统一单元格的高度，就用这个方法*/
//      sheet.setDefaultRowHeight((short)400);    

        /**自适应列宽(不合适。数据量大会卡,1000条2分钟)*/
//      sheet.autoSizeColumn(1, true);//设置第一列单元格宽度自适应


        /**设置样式，独立的一个CellStyle对象，在后面可以把这个CellStyle对象添加到单元格中，就实现了单元格样式*/
        CellStyle style = sxssfWorkbook.createCellStyle();//创建CellStyle对象
        style.setAlignment(HorizontalAlignment.CENTER);//水平居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中

        /**字体样式*/
        HSSFFont font = sxssfWorkbook.createFont();//内容样式
        font.setFontHeightInPoints((short)15);//字体大小
        font.setFontName("Courier New");//字体
//        font.setItalic(true);//是否倾斜
        font.setBold(true);//是否加粗
        /**将字体样式加入CellStyle对象中*/
        style.setFont(font);


        /**样式2(按照同样的方法，可以设置多个CellStyle样式对象，这样你哪里需要用到这个样式，就直接添加进来。这些样式可以封装起来，便于单独调用)*/
        CellStyle style2 = sxssfWorkbook.createCellStyle();
//        style2.setAlignment(HorizontalAlignment.CENTER);//水平居中
//        style2.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
        /**字体样式*/
        HSSFFont font2 = sxssfWorkbook.createFont();//内容样式
        font2.setColor(HSSFFont.COLOR_RED);
        font2.setBold(false);//是否加粗
        /**将字体样式加入Style中*/
        style2.setFont(font2);


        /**合并单元格，四个参数依次为：起始行，终止行，起始列，终止列*/
        CellRangeAddress region1 = new CellRangeAddress(0, 1, (short) 0, (short) 8);
        /**把合并后的单元格添加进sheet对象*/
        sheet.addMergedRegion(region1);

        /**创建 行 对象*/
        HSSFRow headTitle = sheet.createRow(0);//起始行数为0
        headTitle.setHeightInPoints(25);//高度
        /**创建 列 对象*/
        HSSFCell cell = headTitle.createCell(0);//起始列数为0
        /**设置单元格的内容*/
        cell.setCellValue(filename);
        /**设置设置样式*/
        cell.setCellStyle(style);


        String[] head={"标题1","标题2","标题3","标题4","标题5"};//标题集合
        /**继续创建 行 对象*/
        HSSFRow headRow = sheet.createRow(2);//起始行数为2，因为之前我们合并单元格占用了2行，所以这里从第三行开始，索引就是2
        /**继续创建 列 对象*/
        for (int i = 0; i < head.length; i++) {
            headRow.createCell(i).setCellValue(head[i]);//把标题添加到列里面
        }


        /**前面的标题渲染好了后，这里就开始渲染实际数据了，数据一般放在List集合中，进行遍历渲染*/
        for (LinkedHashMap<String, Object> a : list) {
            int j=0;
            /**创建 行 对象*/
            HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);//起始位置就是当前sheet最后一行+1开始
            /**根据行对象，创建列对象*/
            HSSFCell cell1 = dataRow.createCell(j++);
            cell1.setCellValue("我是内容1");
            cell1.setCellStyle(style2);//把之前创建的样式对象CellStyle添加到这个单元格中，这样单元格就有了样式

            dataRow.createCell(j++).setCellValue("我是内容1");
            dataRow.createCell(j++).setCellValue("我是内容1");
            dataRow.createCell(j++).setCellValue("我是内容1");
            dataRow.createCell(j++).setCellValue("我是内容1");
        }


        /****************Excle表格渲染完成后，开始返回流数据*****************/
        /**设置头信息*/
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        /**一定要设置成xlsx格式*/
        response.setHeader("Content-disposition", "attachment;filename=" + filename);
        /**创建一个输出流*/
        ServletOutputStream outputStream = response.getOutputStream();
        /**写入数据*/
        sxssfWorkbook.write(outputStream);
        /**关闭流*/
        outputStream.close();
        sxssfWorkbook.close();
        System.out.println("导出完成");
    }
}